//============================================================================
// Name        : InnerSensorBoard.cpp
// Author      : Vadim
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================
const char* exStr[] = { "INDEX_OUT_OF_RANGE", "NO_ELEMENT_ON_REQUESTED_INDEX" };
//#include "Global_includes.h"
#ifdef LOGGING
#include <typeinfo>
#endif
#ifdef LOG_TO_FILE
#include <fstream>
#endif
//#include <string>
//#include <iostream>
//#include <ctime>
#include <time.h>
#include <windows.h>
#include <process.h>
#include "Global_types.h"
//#include "Logging.h"
//#include "BuildConfig.h"

#include "Sensor.h"
#include "Condition.h"
#include <stdio.h>
#include <conio.h>
#include "Task.h"
#include "TimeManager.h"
#include "Scheduler.h"
#include <list>
using namespace std;
#define FIND( x , a ) (void*) &x.a - (void*) &x //still correct.
struct test {
	int i;
};
int* testFunc(int* h) {
	return h;
}
void functest(int operandNum, ...) {
	va_list vl;
	va_start(vl, operandNum);

	for (uint8_t i = 0; i < operandNum; i++) {
		int val;
		va_arg(vl, Sensor*);
		cout << val;
	}

	va_end(vl);
	cout << "return";
}
//typedef int* (CondVaInt::*pFunc)(int*);
//void PrintFloats(int amount, ...) {
//	int i;
//	int val;
//	va_list vl;
//	va_start(vl, amount);
//	for (i = 0; i < amount; i++) {
//		val = va_arg(vl,int);
//		cout << val;
//	}
//	va_end(vl);
//	printf("\n");
//}
//VOID(CALLBACK *TIMERPROC)(HWND,UINT,UINT,DWORD)
//VOID CALLBACK timerCallback(HWND hwnd, UINT uMsg, UINT_PTR idEvent,
//		DWORD dwTime) {
//	TimeManager::UpdateSystemTime();
//	cout << "Timer called " << *TimeManager::GetSystemTime() << "\n";
//}

//void ThreadCallback(void *args) {
//	SetTimer(NULL, 0, 1, timerCallback);
//	MSG msg;
//	while(*(uint8_t*)args!=TRUE)
//	{
//		GetMessage(&msg, NULL, 0, 0);
//		TranslateMessage(&msg);
//		DispatchMessage(&msg);
//			//cout << "Thread callback "<<clock()<<"\n";
////			Sleep(1000);
////			TimeManager::UpdateSystemTime();
////				cout << "Timer called " << *TimeManager::GetSystemTime() << "\n";
//	}
//	_endthread();
//
//
//}
int main() {
	 CommandHandler::Init();
	 CommandHandler::addMessagebyte('l');
	 CommandHandler::addMessagebyte('s');
	cmd =CommandHandler::retrieveCommandFromString();

		TimeManager::Init();
		//Sleep(1000);
		uint32_t a = 500;
		uint32_t b = 1000;
		uint32_t c = 1500;
		uint32_t d = 2000;
		uint32_t x = 0;
		uint32_t *timeptr;
		//TimeManager::GetSystemTime();
		timeptr = TimeManager::GetSystemTime();
		//Condition<uint32_t > *cond= new Condition<uint32_t > (3,&a, PLUS, &b,PLUS, &x, EQUAL, &c);
	//	Condition<uint32_t> *cond = new Condition<uint32_t>(1, timeptr, MORE_EQUAL, &x);

		Condition<uint32_t> *cond1 = new Condition<uint32_t>(timeptr, MOD, &a,
				EQUAL, &x);
		Condition<uint32_t> *cond2 = new Condition<uint32_t>(timeptr, MOD, &b,
				EQUAL, &x);
		Condition<uint32_t> *cond3 = new Condition<uint32_t>(timeptr, MOD, &c,
				EQUAL, &x);
		Condition<uint32_t> *cond4 = new Condition<uint32_t>(timeptr, MOD, &d,
				EQUAL, &x);
		Sensor *sensTest1 = new Sensor((char*)"Sens1");
		Sensor *sensTest2 = new Sensor((char*)"Sens2");
		Sensor *sensTest3 = new Sensor((char*)"Sens3");
		Sensor *sensTest4 = new Sensor((char*)"Sens4");
		ErrorCode (*funcx)(void *args);
		funcx = (ErrorCode (*)(void *args))&Sensor::scan;
		Task *task1 = new Task((char*)"Task1", funcx,(void*)sensTest1, cond1,ENABLED);
		Task *task2 = new Task((char*)"Task2", funcx,(void*)sensTest2, cond2, ENABLED);
		Task *task3 = new Task((char*)"Task3", funcx,(void*)sensTest3, cond3,ENABLED);
		Task *task4 = new Task((char*)"Task4", funcx,(void*)sensTest4, cond4, ENABLED);
		task1->addNextTask(task2);
		task2->addNextTask(task1);
		Scheduler::init();
		Scheduler::addTask(task1,SYS_TICK);
		Scheduler::addTask(task2,SYS_TICK);
		Scheduler::addTask(task3,SYS_TICK);
		Scheduler::addTask(task4,SYS_TICK);
		Scheduler::start();
	////Sheduler::addTask()

	int i = 1000;
//	while (i--) {
//		cout << "\n a = " << (a);
//		cout << "\n b = " << (b);
//		cout << "\n x = " << (x);
//		cout << "\n c = " << (c);
//		cout << "\n a+b+x = " << ((uint16_t)(a + b + x))<<"\n";
//		task->run((void *)&c);
//		if (cond->check()==true)
//		{
//			cout << "Oh yeah! Condition has been met!\n\n";
//			break;
//		} else {
//			cout << "Condition hasn't been met\n";
//		}
//		a+=1;
//	}
//	volatile uint32_t prevTime = *timeptr;
//	bool check = false;
//	while (check == false) {
//		//cout << "no!\n";
//		if (prevTime != *timeptr) {
//			prevTime = *timeptr;
//			task = task->run();
//		}
////		if (*timeptr >= x) {
////
////			x += 1000;
////			cout<<"time!\n";
////		}
//
//		if (*timeptr >= 10000) {
//			break;
//		}
//		if (cond->check() == true) {
//			Log("Oh yeah! Condition has been met!");
//			//cout << "Oh yeah! Condition has been met!\n\n";
//			check = true;
//		}
//		if (*timeptr >= 3000) {
//			cout << "failed!\n\n";
//			break;
//		}
	//	usleep(10);
//	}
	//Sleep(5000L);
	///WaitForSingleObject( hThread, INFINITE );
	TimeManager::DeInit();
	cout << "trying to stop the thread!\n";
	//_endthreadex(hThread);
	cout << "Type any key to exit! ";
	getch();
	//_endthreadex(hThread);
	cout << "\n";
	Log("Exit! ");
	Sleep(2000);
	return 0;
}
